/**
 * @author harry
 * @date 2022/2/23/20:55
 */

package com.serviceOrchestration.service;

import com.serviceOrchestration.dao.AdminDao;
import com.serviceOrchestration.dao.RedisDao;
import com.serviceOrchestration.dao.UserDao;
import com.serviceOrchestration.exception.LoginException;
import com.serviceOrchestration.exception.NotFoundException;
import com.serviceOrchestration.exception.ServerException;
import com.serviceOrchestration.pojo.Admin;
import com.serviceOrchestration.pojo.User;
import com.serviceOrchestration.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class LoginService {

    private final AdminDao adminDao;
    private final UserDao userDao;
    private final RedisDao redisDao;

    @Autowired
    public LoginService(AdminDao adminDao, UserDao userDao, RedisDao redisDao) {
        this.adminDao = adminDao;
        this.userDao = userDao;
        this.redisDao = redisDao;
    }

    /**
     * 管理员登录
     * @param id 账号
     * @param password 密码
     * @return 成功则生成token、获取role放在ReturnData，失败则返回错误ReturnData
     */
    public Map<String, String> adminLogin(String id, String password) throws NotFoundException, LoginException {
        // 1.缺少参数
        if(id == null || password == null) {
            throw new IllegalArgumentException("lack of params");
        }

        List<Admin> accountList = adminDao.selectById(id);
        // 2.没有这个账号
        if(accountList.isEmpty()) {
            throw new NotFoundException("no such account");
        }
        // 3.找到了不止一个账号，肯定服务器问题
        if(accountList.size() > 1) {
            throw new ServerException("duplicate account");
        }

        Admin admin = accountList.get(0);
        // 4.密码错误
        if(!admin.getPassword().equals(password)) {
            throw new IllegalArgumentException("wrong password");
        }
        String redisKey = RedisDao.TOKEN_KEY_PREFIX + id;
        String tokenInRedis = redisDao.get(redisKey);
        // 5.已经登录过
        if(tokenInRedis != null) {
            throw new LoginException("already logged");
        }
        // 6.没有登录或已经过期，生成新token
        String token = JwtUtil.generateToken(admin);
        redisDao.setAndExpire(redisKey, "", JwtUtil.EXPIRATION);
        Map<String, String> map = new HashMap<>();
        map.put("token", token);
        map.put("role", admin.getRole());
        return map;
    }

    public Map<String, Object> userLogin(String id, String password) throws NotFoundException, LoginException {
        // 1.缺少参数
        if(id == null || password == null) {
            throw new IllegalArgumentException("lack of params");
        }

        List<User> userList = userDao.selectById(id);
        // 2.没有这个账号
        if(userList.isEmpty()) {
            throw new NotFoundException("no such account");
        }
        // 3.找到了不止一个账号，肯定服务器问题
        if(userList.size() > 1) {
            throw new ServerException("duplicate account");
        }

        User user = userList.get(0);
        // 4.密码错误
        if(!user.getPassword().equals(password)) {
            throw new IllegalArgumentException("wrong password");
        }
        String redisKey = RedisDao.TOKEN_KEY_PREFIX + id;
        String tokenInRedis = redisDao.get(redisKey);
        // 5.已经登录过
        if(tokenInRedis != null) {
            throw new LoginException("already logged");
        }
        // 6.没有登录或已经过期，生成新token
        String token = JwtUtil.generateToken(user);
        redisDao.setAndExpire(redisKey, "", JwtUtil.EXPIRATION);

        HashMap<String, Object> ret = new HashMap<>();
        ret.put("token", token);
        ret.put("user", user);
        return ret;
    }

    public boolean logout(String token) {
        String sub = JwtUtil.getSubjectFromToken(token);
        redisDao.delete(RedisDao.TOKEN_KEY_PREFIX + sub);
        return true;
    }
}
